package com.amazon.jobtest;


import java.util.Collections;
import java.util.Comparator;
import java.util.LinkedList;
import java.util.List;

import com.amazon.jobtest.exception.BRException;
import com.amazon.jobtest.util.TestScoreComparator;

public class Student {

	private List<TestResult> testResultList;
	private String studentId;
	/** Specifies how many tests are used to obtain the average default */
	public static final int TEST_GROUP_SIZE = 5;

	public Student() {
		setTestResultList(new LinkedList<TestResult>());
	}

	public Boolean addTestResult(TestResult testResult) {
		return testResultList.add(testResult);
	}


	public List<TestResult> getTestResultList() {
		return testResultList;
	}

	private void setTestResultList(List<TestResult> testResultList) {
		this.testResultList = testResultList;
	}
	

	public String getStudentId() {
		return studentId;
	}

	public void setStudentId(String studentId) {
		this.studentId = studentId;
	}

	/**
	 * Calculates the average of the student tests which had the highest scores
	 * 
	 * @return {@link Float} the average
	 * @exception Exception
	 *                if the student doesn't has enough tests to calculate the
	 *                average (less than testGroupSize)
	 */
	public Float getAverageTestResult(int testGroupSize, Comparator<TestResult> comparator) {
		if (testResultList.size() < testGroupSize) {
			StringBuilder exceptionMsg = new StringBuilder();
			// TODO intenacionalization msg files
			exceptionMsg.append("This student just made "
					+ testResultList.size() + " tests");
			exceptionMsg.append("\n He must have at least  " + TEST_GROUP_SIZE
					+ " tests");
			throw new BRException(exceptionMsg.toString());
		}
		// sorts the list before the operations
		Collections.sort(testResultList, comparator);
		float totalScore = 0;
		int iterations = 0;
		for (TestResult test : testResultList) {
			totalScore += test.getScore();
			iterations++;
			if (iterations == testGroupSize) {
				break;
			}
		}
		float average = totalScore / testGroupSize;

		return average;
	}
	public Float getAverageTestResult(){
		return this.getAverageTestResult(TEST_GROUP_SIZE, new TestScoreComparator());
	}


	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result
				+ ((studentId == null) ? 0 : studentId.hashCode());
		return result;
	}
	/**
	 * Equals based on the studentId to use indexOf Collection method 
	 */
	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		Student other = (Student) obj;
		if (studentId == null) {
			if (other.studentId != null)
				return false;
		} else if (!studentId.equals(other.studentId))
			return false;
		return true;
	}
	
	

}
